#include "preHeader.h"
#include "TransMgr.h"

TransMgr::TransMgr()
{
}

TransMgr::~TransMgr()
{
}

void TransMgr::RunGC()
{
	while (!m_recycleBin.empty()) {
		auto& pair = m_recycleBin.front();
		if (pair.second < GET_UNIX_TIME) {
			m_recycleBin.pop();
		} else {
			break;
		}
	}
	while (!m_recycleBin4Client.empty()) {
		auto& pair = m_recycleBin4Client.front();
		if (pair.second < GET_UNIX_TIME) {
			m_recycleBin4Client.pop();
		} else {
			break;
		}
	}
}

void TransMgr::AddClient(Client* pClient)
{
	std::lock_guard<std::shared_mutex> lock(m_clientMutex);
	m_clientMap.emplace(pClient->uid, pClient);
}

void TransMgr::RemoveClient(uint32 uid)
{
	std::lock_guard<std::shared_mutex> lock(m_clientMutex);
	auto itr = m_clientMap.find(uid);
	if (itr != m_clientMap.end()) {
		m_recycleBin4Client.emplace(
			itr->second, GET_UNIX_TIME + GC_DELAY_TIME);
		m_clientMap.erase(itr);
	}
}

const TransMgr::Client* TransMgr::GetClient(uint32 uid)
{
	std::shared_lock<std::shared_mutex> lock(m_clientMutex);
	auto itr = m_clientMap.find(uid);
	return itr != m_clientMap.end() ? itr->second : NULL;
}

void TransMgr::AddGateServer(GateServerSession* pSession)
{
	std::lock_guard<std::shared_mutex> lock(m_gateServerMutex);
	m_gateServerMap.emplace(pSession->gsGateSN(), pSession);
}

void TransMgr::RemoveGateServer(GateServerSession* pSession)
{
	std::lock_guard<std::shared_mutex> lock(m_gateServerMutex);
	if (m_gateServerMap.erase(pSession->gsGateSN()) != 0) {
		m_recycleBin.emplace(
			pSession->GetConnection(), GET_UNIX_TIME + GC_DELAY_TIME);
	}
}

GateServerSession* TransMgr::GetGateServer(uint32 gsGateSN)
{
	std::shared_lock<std::shared_mutex> lock(m_gateServerMutex);
	auto itr = m_gateServerMap.find(gsGateSN);
	return itr != m_gateServerMap.end() ? itr->second : NULL;
}

void TransMgr::RemoveAllClient()
{
	std::lock_guard<std::shared_mutex> lock(m_clientMutex);
	for (auto& pair : m_clientMap) {
		m_recycleBin4Client.emplace(
			pair.second, GET_UNIX_TIME + GC_DELAY_TIME);
	}
	m_clientMap.clear();
}

void TransMgr::UpdateGateServerGSSN(uint32 oldGsGateSN, GateServerSession* pSession)
{
	std::lock_guard<std::shared_mutex> lock(m_gateServerMutex);
	m_gateServerMap.erase(oldGsGateSN);
	m_gateServerMap.emplace(pSession->gsGateSN(), pSession);
}

void TransMgr::SendError2ClientSafe(uint32 uid, GErrorCode error)
{
	NetPacket pack(SMSG_ERROR);
	pack << (s32)error;
	SendPacket2ClientSafe(uid, pack);
}

void TransMgr::SendPacket2ClientSafe(uint32 uid, const INetPacket& data)
{
	auto pClient = GetClient(uid);
	if (pClient != NULL) {
		auto pSession = GetGateServer(pClient->gsGateSN);
		if (pSession != NULL) {
			NetPacket pck(SGT_TRANS_CLIENT_PACKET);
			pck << pClient->gateClientSN;
			pSession->PushSendPacket(pck, data);
		}
	}
}

void TransMgr::BroadcastPacket2AllClientSafe(const INetPacket& data)
{
	NetPacket pck(SGT_PUSH_PACKET_TO_ALL_CLIENT);
	BroadcastPacket2AllGateServerSafe(pck, data);
}

void TransMgr::BroadcastPacket2AllGateServerSafe(const INetPacket& pck)
{
	std::shared_lock<std::shared_mutex> lock(m_gateServerMutex);
	for (const auto& pair : m_gateServerMap) {
		pair.second->PushSendPacket(pck);
	}
}

void TransMgr::BroadcastPacket2AllGateServerSafe(const INetPacket& pck, const INetPacket& data)
{
	std::shared_lock<std::shared_mutex> lock(m_gateServerMutex);
	for (const auto& pair : m_gateServerMap) {
		pair.second->PushSendPacket(pck, data);
	}
}
